package com.zixi.ai.framework.controller;

import cn.hutool.core.date.DateUtil;
import com.zixi.ai.common.annotation.Log;
import com.zixi.ai.common.domain.R;
import com.zixi.ai.common.enums.BusinessType;
import com.zixi.ai.common.enums.DataStatus;
import com.zixi.ai.common.utils.ReflectUtils;
import com.zixi.ai.framework.dao.spec.MySpecification;
import com.zixi.ai.framework.dao.spec.Restrictions;
import com.zixi.ai.framework.entity.BaseEntity;
import com.zixi.ai.framework.entity.ExtBaseEntity;
import com.zixi.ai.framework.entity.page.QueryPageSupport;
import com.zixi.ai.framework.service.BaseService;
import com.zixi.ai.framework.utils.SecurityUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author mqiqe
 */
@Slf4j
@RestController
public abstract class BaseTemplateController<S extends BaseService<T, ID>, T extends BaseEntity, ID> {
    @Autowired
    protected S service;
    /**
     * 分页
     */
    @Operation(summary = "分页列表",
            parameters = {
                    @Parameter(name = "page", required = true, description = "页码"),
                    @Parameter(name = "size", required = true, description = "每页数量"),
                    @Parameter(name = "orderByColumn", description = "排序列"),
                    @Parameter(name = "orderBy", description = "排序的方向 desc 或者 asc."),
            }
    )
    @PostMapping("page")
    public R<Page<T>> postPage(@RequestBody(required = false) T query) {
        MySpecification<T> spec = convertQuery(query);
        return R.ok(service.findPage(spec, QueryPageSupport.buildPageRequest()));
    }

    public MySpecification<T> convertQuery(T query) {
        MySpecification<T> spec = new MySpecification<>();
        if (query instanceof ExtBaseEntity) {
            spec.add(Restrictions.eq("tenantId", SecurityUtils.getTenantId()));
        }
        if (query != null && query.getParams() != null) {
            query.getParams().forEach((k, v) -> {
                if (v != null && !"".equals(v)) {
                    if (v instanceof Number || v instanceof String) {
                        if (ReflectUtils.findField(query.getClass(), k) != null) {
                            if ("name".equalsIgnoreCase(k) && v instanceof String) {
                                spec.add(Restrictions.like(k, (String) v));
                            } else {
                                spec.add(Restrictions.eq(k, v));
                            }
                        }
                    }
                    if ("startTime".equalsIgnoreCase(k)) {
                        if (v instanceof String) {
                            v = DateUtil.parse((String) v);
                        }
                        spec.add(Restrictions.gte("createTime", v));
                    }
                    if ("endTime".equalsIgnoreCase(k)) {
                        if (v instanceof String) {
                            v = DateUtil.parse((String) v);
                        }
                        spec.add(Restrictions.lte("createTime", v));
                    }
                }
            });
        }
        return spec;
    }


    /**
     * 数据
     */
    @Operation(summary = "根据ID获取详细数据")
    @GetMapping()
    public R<T> getById(@RequestParam("id") ID id) {
        return R.ok(service.findById(id).orElse(null));
    }

    /**
     * 列表
     */
    @Operation(summary = "列表查询数据")
    @PostMapping("list")
//    @PreAuthorize("@ss.hasPermi('list')")
    public R<List<T>> postList(@RequestBody(required = false) T query) {
        MySpecification<T> spec = convertQuery(query);
        return R.ok(service.findAll(spec));
    }

    /**
     * 添加
     */
    @Operation(summary = "增加数据")
    @PostMapping()
    @Log(title = "增加", businessType = BusinessType.INSERT)
    public R<T> create(@Valid @RequestBody T t) {
        t = doPreSave(t);
        service.save(t);
        t = doAfterSave(t);
        return R.ok(t);
    }

    public T doAfterSave(T t) {
        return t;
    }

    /**
     * 保存之前初始化配置
     *
     * @param t 保存实体数据
     */
    public T doPreSave(T t) {
        return t;
    }

    /**
     * 修改
     */
    @Operation(summary = "修改数据")
    @PutMapping()
    @Log(title = "修改", businessType = BusinessType.UPDATE)
    public R<T> update(@Valid @RequestBody T t) {
        t = doPreUpdate(t);
        service.save(t);
        t = doAfterUpdate(t);
        return R.ok(t);
    }

    public T doPreUpdate(@Valid T t) {
        return t;
    }

    public T doAfterUpdate(T t) {
        return t;
    }

    /**
     * 删除
     */
    @Operation(summary = "删除数据")
    @DeleteMapping()
    @Log(title = "删除", businessType = BusinessType.DELETE)
    public R<Boolean> del(@RequestParam ID[] ids) {
        doPreDel(ids);
        for (ID id : ids) {
            T data = service.findById(id).orElse(null);
            if (data instanceof ExtBaseEntity) {
                ((ExtBaseEntity) data).setDelFlag(DataStatus.YES.getCode());
                service.save(data);
            } else {
                service.del(id);
            }
        }
        return R.ok(Boolean.TRUE);
    }

    public void doPreDel(ID[] ids) {
    }
}
